package com.ajz.config.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.GenericFilterBean;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;

public class JwtFilter extends GenericFilterBean {
	public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
            throws IOException, ServletException {
        // Change the req and res to HttpServletRequest and HttpServletResponse
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        
        // Get authorization from Http request
        final String authHeader = request.getHeader("authorization");

        // If the Http request is OPTIONS then just return the status code 200
        // which is HttpServletResponse.SC_OK in this code
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);

            chain.doFilter(req, res);
        }else {

            // Check the authorization, check if the token is started by "Bearer "
            if (authHeader == null || !authHeader.startsWith("beaner ")) {
                throw new ServletException("Missing or invalid Authorization header");
            }
            JwtTokenUtil jwtTokenUtil = SpringUtil.getBean(JwtTokenUtil.class);
            UserDetailsService userDetailsService = SpringUtil.getBean(UserDetailsService.class);
            // Then get the JWT token from authorization
            final String token = authHeader.substring(7);
            String username = jwtTokenUtil.getUsernameFromToken(token);
            if (username == null) {
            	vtoken(response);
			}
            //UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if(!jwtTokenUtil.validateToken(token, username)) {
            	vtoken(response);
            }
            try {
                // Use JWT parser to check if the signature is valid with the Key "secretkey"
                final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();

                // Add the claim to request header
                request.setAttribute("claims", claims);
            } catch (final SignatureException e) {
                throw new ServletException("Invalid token");
            }

            chain.doFilter(req, res);
        }
    }
	/**
	 * 验证token
	 * @param response
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	private void vtoken(HttpServletResponse response) throws JsonProcessingException, IOException {
		response.setCharacterEncoding("UTF-8");  
    	response.setContentType("application/json; charset=utf-8"); 
    	response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		ObjectMapper mapper = new ObjectMapper();
//		resultMsg = new ResultMsg(ResultStatusCode.INVALID_TOKEN.getErrcode(), ResultStatusCode.INVALID_TOKEN.getErrmsg(), null);
		response.getWriter().write(mapper.writeValueAsString("Invalid token"));
		return;
	}
}
